/**
  ******************************************************************************
  * @file    Key.c
  * @author  Qilong Huang
  * @version V0.0.1
  * @date    04-03-2020
  * @brief   This file contains functions to initialize the OS.  
  *				 
  *          
  ******************************************************************************
  * @attention
  *
  * <h2><center>&copy; KION(SZ) R&D Center
  *
  * Licensed under KION, (the "License");
  *
  ******************************************************************************
  */

/* Includes ------------------------------------------------------------------*/

/*===============================================[ private includes  ]================================================*/

#include "stm32f10x.h"
#include "Key.h"
#include "switch.h"
#include "can_canopen.h"
#include "Icons.h"
/*===============================================[ private defines   ]================================================*/
#define DEBOUNCE_KEY_CONST	        20
#define LONG_KEY_CONST		  	    2000 
#define UP_DOWN_CONST		        1500
#define DEBOUNCE_KEY_PRESSED	    200
#define SHORT_KEY_CONST		  	    50 
#define KEY_COUNT_LOCK				0x01
#define KEY_COUNT_UNLOCK			0x00
/*===============================================[ private datatypes ]================================================*/

/*===============================================[ private variables ]================================================*/
//static u8 ShortEnterEable = 0;


/*===============================================[ public variables ]================================================*/
u8 key_serviced = 0;//just for enter, left ,right key
volatile u16 key_up_value;
volatile u16 key_up_time_value;
volatile u16 key_down_value;
volatile u16 key_down_time_value;
volatile u16 key_enter_value;


U8 Key_status[4];
U8 SwitchKeyStatus;
static U8 start_flag = 0;
U16 SoftCloseCounter;
U8 SoftCloseFlag = FALSE;

/*===============================================[ private functions ]================================================*/

/*================================================[ inline functions ]================================================*/

/*================================================[ public functions ]================================================*/


/*================================================[ public definions ]================================================*/



/**
* @brief	This task samples the pushbuttons
* @param	none
* @note     none
* @retval   none
*/
void sample_PB_task(void const *argument) 
{
	static u16 key1_count = 0, key2_count = 0, key3_count = 0, key4_count = 0;
	static u16 key1_lock = 0, key2_lock = 0, key3_lock = 0, key4_lock = 0;
	Pin_Code.PinCode_Pt = 0;
	while (TRUE)
	{
		if((switches_current & KEY4_IN) == 0) 
		{
			if(key4_lock == KEY_COUNT_UNLOCK)		//key4 is active
			{
				key4_count ++;
				if(key4_count >= SHORT_KEY_CONST)
				{
					Key_status[0] = KEY_SHORT_PRESS;
					key4_lock = KEY_COUNT_LOCK;		//key4 is locked
				}				
			}
		}
		if((switches_current & KEY3_IN) == 0) 
		{
			if(key3_lock == KEY_COUNT_UNLOCK)		//key3 is active
			{
				key3_count ++;
				if(key3_count >= SHORT_KEY_CONST)
				{
					Key_status[1] = KEY_SHORT_PRESS;
					key3_lock = KEY_COUNT_LOCK;		//key3 is locked
				}				
			}
		}
		if((switches_current & KEY2_IN) == 0) 
		{
			if(key2_lock == KEY_COUNT_UNLOCK)		//key2 is active
			{
				key2_count ++;
				if(key2_count >= SHORT_KEY_CONST)
				{
					Key_status[2] = KEY_SHORT_PRESS;
					key2_lock = KEY_COUNT_LOCK;		//key2 is locked
				}				
			}
			if(key2_lock == KEY_COUNT_LOCK)         //key2 long key input detect
            {
                key2_count ++;
                if(key2_count >= LONG_KEY_CONST)
                {
                    Key_status[2] = KEY_LONG_PRESS;
                }
            }
		}
		if((switches_current & KEY1_IN) == 0) 
		{
			if(key1_lock == KEY_COUNT_UNLOCK)		//key1 is active
			{
				key1_count ++;
				if(key1_count >= SHORT_KEY_CONST)
				{
					Key_status[3] = KEY_SHORT_PRESS;
					key1_lock = KEY_COUNT_LOCK;		//key1 is locked
				}				
			}
		}
        if((switches_current & KEY_SWITCH_IN) == 0)                      //Turn off the dshb
        {
			Screen_Mode = MODE_Standby;
            start_flag = 0;
        }
        else if((switches_current & KEY_SWITCH_IN) == KEY_SWITCH_IN)    //Turn on the Dshb
        {
            if(start_flag == 0)
            {
                start_flag = 1;
                Screen_Mode = MODE_PinCode;
            }
        }
		if((switches_current & 0x1f) == 0x1f)		//release all the key
		{
			key1_lock = KEY_COUNT_UNLOCK;
			key1_count = 0;
			key2_lock = KEY_COUNT_UNLOCK;
			key2_count = 0;
			key3_lock = KEY_COUNT_UNLOCK;
			key3_count = 0;
			key4_lock = KEY_COUNT_UNLOCK;
			key4_count = 0;
		}
		key_handler();

		task_status[SAMPLE_PB_ID] = ALIVE;
		osDelay(SAMPLE_PB_ITV);
	}  // end while infinite loop
}  // end sample_PB_task()

/**
* @brief	This task samples the pushbuttons
* @param	none
* @note     none
* @retval   none
*/
void key_handler(void)
{
	//Pin code input mode
	static Screen_Mode_type prev_mode;
	u8 i = 0;
	if(Screen_Mode == MODE_PinCode)
	{
		if(Key_status[0] == KEY_SHORT_PRESS)
		{
			Pin_Code.PinCodeNum[Pin_Code.PinCode_Pt ++] = 1;
			Key_status[0] = RESET_KEY_STATUS;
		}
		if(Key_status[1] == KEY_SHORT_PRESS)
		{
			Pin_Code.PinCodeNum[Pin_Code.PinCode_Pt ++] = 2;
			Key_status[1] = RESET_KEY_STATUS;
		}
		if(Key_status[2] == KEY_SHORT_PRESS)
		{
			Pin_Code.PinCodeNum[Pin_Code.PinCode_Pt ++] = 3;
			Key_status[2] = RESET_KEY_STATUS;
		}
		if(Key_status[3] == KEY_SHORT_PRESS)
		{
			Pin_Code.PinCodeNum[Pin_Code.PinCode_Pt ++] = 4;
			Key_status[3] = RESET_KEY_STATUS;
		}
	}
	if(Screen_Mode == MODE_InitErrCode)
	{
		if(Key_status[0] == KEY_SHORT_PRESS)
		{
			Key_status[0] = RESET_KEY_STATUS;
		}
		if(Key_status[3] == KEY_SHORT_PRESS)
		{
			Key_status[3] = RESET_KEY_STATUS;
			Screen_Mode = MODE_ShowTime;
            Err_Code_Hide_flag = TRUE;
		}		
	}
	if(Screen_Mode == MODE_ShowTime)
	{
		if(Key_status[0] == KEY_SHORT_PRESS)
		{
			Key_status[0] = RESET_KEY_STATUS;
			Screen_Mode = MODE_ShowHourmeter;
		}
		if(Key_status[2] == KEY_LONG_PRESS)
        {
			SoftCloseCounter ++;
			if(SoftCloseCounter >= 200)
			{
				Screen_Mode = MODE_Standby;
			}
            else
			{
				SoftCloseFlag = TRUE;
			}		
        }
	}
	if(Screen_Mode == MODE_ShowHourmeter)
	{
		if(Key_status[1] == KEY_SHORT_PRESS)
		{
			Key_status[1] = RESET_KEY_STATUS;
			Screen_Mode = MODE_ShowTime;
		}
		if(Key_status[0] == KEY_SHORT_PRESS)
		{
			Key_status[0] = RESET_KEY_STATUS;
			Screen_Mode = MODE_ShowService;
		}
	}
	if(Screen_Mode == MODE_ShowService)
	{
		if(Key_status[0] == KEY_SHORT_PRESS)
		{
			Key_status[0] = RESET_KEY_STATUS;
            if(Err_Code_Exist_flag == TRUE)
            {
			    Screen_Mode = MODE_UserErrCode;
            }
            else
            {
                Screen_Mode = MODE_ShowService;
            }
		}
		if(Key_status[1] == KEY_SHORT_PRESS)
		{
			Key_status[1] = RESET_KEY_STATUS;
			Screen_Mode = MODE_ShowHourmeter;
            if(Err_Oil_Exist_flag == TRUE)
            {
                Screen_Mode = MODE_OilErrCode;
            }
            else if(Err_Temp_Hide_flag == TRUE)
            {
                Screen_Mode = MODE_TempErrCode_Next;
            }
            else if(Err_Maint_Exist_flag == TRUE)
            {
                Screen_Mode = MODE_MaintErrCode;
            }
			else if(Err_BatCutoff_Exist_flag == TRUE)
			{
				Screen_Mode = Mode_BatCutoff;
			}
			else if(Err_Batlow_Exist_flag == TRUE)
			{
				Screen_Mode = Mode_BatLow;
			}
		}
		if(Key_status[2] == KEY_LONG_PRESS)
        {
			Screen_Mode = MODE_Admin;
            for(i = 0; i < 4; i ++)
			{
				Pin_Code.PinCodeNum[i] = 0;				
			}
            Pin_Code.PinCode_Pt = 0;	
        }
	}
	if(Screen_Mode == MODE_UserErrCode)
	{
		if(Key_status[1] == KEY_SHORT_PRESS)
		{
			Key_status[1] = RESET_KEY_STATUS;
			Screen_Mode = MODE_ShowService;
		}	
	    if(Key_status[3] == KEY_SHORT_PRESS)
		{
			prev_mode = Screen_Mode;
			Key_status[3] = RESET_KEY_STATUS;
		}	
	}
	if((Screen_Mode == MODE_ShowHourmeter) || (Screen_Mode == MODE_ShowTime) || (Screen_Mode == MODE_ShowService))
	{	
	    if(Key_status[3] == KEY_SHORT_PRESS)
		{
			prev_mode = Screen_Mode;
			Key_status[3] = RESET_KEY_STATUS;
			Screen_Mode = MODE_AdjustLightness;
		}	
	}
	if(Screen_Mode == MODE_AdjustLightness)
	{
		LCD_AdjustbarExitCounter ++;
		if(Key_status[0] == KEY_SHORT_PRESS)
		{
			Key_status[0] = RESET_KEY_STATUS;
            LCD_Bklight ++;
			if(LCD_Bklight >= MAX_LCD_BKLEVEL)
			{
			    LCD_Bklight = MAX_LCD_BKLEVEL;
			}
            menu_needs_ee = 1;
            menu_ee_index = VAR_LCD_BKLIGHT_INDEX;
			LCD_AdjustbarExitCounter = 0;
		}	
		if(Key_status[1] == KEY_SHORT_PRESS)
		{
			Key_status[1] = RESET_KEY_STATUS;
			LCD_Bklight --;
			if(LCD_Bklight <= MIN_LCD_BKLEVEL)
			{
			    LCD_Bklight = MIN_LCD_BKLEVEL;
			}
            menu_needs_ee = 1;
            menu_ee_index = VAR_LCD_BKLIGHT_INDEX;
			LCD_AdjustbarExitCounter = 0;
		}	
	    if((Key_status[3] == KEY_SHORT_PRESS) || (LCD_AdjustbarExitCounter >= 1000))
		{
			Key_status[3] = RESET_KEY_STATUS;
			Screen_Mode = prev_mode;
			LCD_AdjustbarExitCounter = 0;
		}		    
	}
	if(Screen_Mode == MODE_OilErrCode)
	{	
	    if(Key_status[0] == KEY_SHORT_PRESS)
		{
            Err_Oil_Hide_flag = TRUE;
			prev_mode = Screen_Mode;
			Key_status[0] = RESET_KEY_STATUS;
			Screen_Mode = MODE_ShowService;
		}	
	    if(Key_status[3] == KEY_SHORT_PRESS)
		{
            Err_Oil_Hide_flag = TRUE;
            prev_mode = Screen_Mode;
			Key_status[3] = RESET_KEY_STATUS;
			Screen_Mode = MODE_DeleteErrCode_Diag;
		}
	}
	if(Screen_Mode == MODE_TempErrCode)
	{	
	    if(Key_status[0] == KEY_SHORT_PRESS)
		{
            Err_Temp_Hide_flag = TRUE;
			prev_mode = Screen_Mode;
			Key_status[0] = RESET_KEY_STATUS;
			Screen_Mode = MODE_TempErrCode_Next;
		}	
	    if(Key_status[3] == KEY_SHORT_PRESS)
		{
            Err_Temp_Hide_flag = TRUE;
            prev_mode = Screen_Mode;
			Key_status[3] = RESET_KEY_STATUS;
			Screen_Mode = MODE_DeleteErrCode_Diag;
		}
	}
	if(Screen_Mode == MODE_TempErrCode_Next)
	{	
	    if(Key_status[0] == KEY_SHORT_PRESS)
		{
			prev_mode = Screen_Mode;
			Key_status[0] = RESET_KEY_STATUS;
			Screen_Mode = MODE_ShowService;
		}	
	    if(Key_status[1] == KEY_SHORT_PRESS)
		{
			prev_mode = Screen_Mode;
			Key_status[1] = RESET_KEY_STATUS;
			Screen_Mode = MODE_TempErrCode;
		}	
	    if(Key_status[3] == KEY_SHORT_PRESS)
		{
            prev_mode = Screen_Mode;
			Key_status[3] = RESET_KEY_STATUS;
			Screen_Mode = MODE_DeleteErrCode_Diag;
		}
	}
    if(Screen_Mode == MODE_MaintErrCode)
    {
	    if(Key_status[0] == KEY_SHORT_PRESS)
		{
            Err_Maint_Hide_flag = TRUE;
			prev_mode = Screen_Mode;
			Key_status[0] = RESET_KEY_STATUS;
			Screen_Mode = MODE_ShowService;
		}	
	    if(Key_status[3] == KEY_SHORT_PRESS)
		{
            Err_Maint_Hide_flag = TRUE;
            prev_mode = Screen_Mode;
			Key_status[3] = RESET_KEY_STATUS;
			Screen_Mode = MODE_DeleteErrCode_Diag;
		}    
    }
	if(Screen_Mode == Mode_BatLow)
	{
	    if(Key_status[0] == KEY_SHORT_PRESS)
		{
            Err_Batlow_Hide_flag = TRUE;
			prev_mode = Screen_Mode;
			Key_status[0] = RESET_KEY_STATUS;
			Screen_Mode = MODE_ShowService;
		}	
	    if(Key_status[3] == KEY_SHORT_PRESS)
		{
            Err_Batlow_Hide_flag = TRUE;
            prev_mode = Screen_Mode;
			Key_status[3] = RESET_KEY_STATUS;
			Screen_Mode = MODE_DeleteErrCode_Diag;
		}    		
	}
	if(Screen_Mode == Mode_BatCutoff)
	{
	    if(Key_status[0] == KEY_SHORT_PRESS)
		{
            Err_BatCutoff_Hide_flag = TRUE;
			prev_mode = Screen_Mode;
			Key_status[0] = RESET_KEY_STATUS;
			Screen_Mode = MODE_ShowService;
		}	
	    if(Key_status[3] == KEY_SHORT_PRESS)
		{
            Err_BatCutoff_Hide_flag = TRUE;
            prev_mode = Screen_Mode;
			Key_status[3] = RESET_KEY_STATUS;
			Screen_Mode = MODE_DeleteErrCode_Diag;
		}    		
	}
    if(Screen_Mode == MODE_DeleteErrCode_Diag)
    {
	    if(Key_status[0] == KEY_SHORT_PRESS)
		{
            if(prev_mode == MODE_OilErrCode)
            {
                OilErrCodeDealFlag = FALSE;
            }
            if((prev_mode == MODE_TempErrCode) || (prev_mode == MODE_TempErrCode_Next))
            {
                TempurateErrCodeDealFlag = FALSE;
            }
            if(prev_mode == MODE_MaintErrCode)
            {
                MaintErrCodeDealFlag = FALSE;
            }
			if(prev_mode == Mode_BatCutoff)
			{
				BatCutoffDealFlag = FALSE;
			}
			if(prev_mode == Mode_BatLow)
			{
				BatLowDealFlag = FALSE;
			}
			Key_status[0] = RESET_KEY_STATUS;
		}	
	    if(Key_status[1] == KEY_SHORT_PRESS)
		{
			Screen_Mode = prev_mode;
			Key_status[1] = RESET_KEY_STATUS;
		}	
    }
    if(Screen_Mode == MODE_DigiCodeEnsure)
    {
		u8 i;
	    if(Key_status[0] == KEY_SHORT_PRESS)
		{
            set_digicode();
			Screen_Mode = MODE_ShowService;
			Key_status[0] = RESET_KEY_STATUS;
		}	
	    if(Key_status[1] == KEY_SHORT_PRESS)
		{
            for(i = 0; i < 4; i ++)
		    {
			    Pin_Code.PinCodeNum[i] = 0;
			    Pin_Code.PinCode_Pt = 0;
		    }
			Screen_Mode = MODE_ResetPincode;
			Key_status[1] = RESET_KEY_STATUS;
		}	
    }
	if(Screen_Mode == MODE_Standby)
	{
		if(((Key_status[0] == KEY_SHORT_PRESS) || (Key_status[1] == KEY_SHORT_PRESS) || (Key_status[2] == KEY_SHORT_PRESS) || (Key_status[3] == KEY_SHORT_PRESS)) \
		&& ((switches_current & KEY_SWITCH_IN) != 0))
		{
            start_flag = 1;
            Screen_Mode = MODE_PinCode;
            Key_status[0] = RESET_KEY_STATUS;
            Key_status[1] = RESET_KEY_STATUS;
            Key_status[2] = RESET_KEY_STATUS;
            Key_status[3] = RESET_KEY_STATUS;
		}
		else
		{
		    Key_status[0] = RESET_KEY_STATUS;
            Key_status[1] = RESET_KEY_STATUS;
            Key_status[2] = RESET_KEY_STATUS;
            Key_status[3] = RESET_KEY_STATUS;
			for(i = 0; i < 4; i ++)
		    {
			    Pin_Code.PinCodeNum[i] = 0;
			    Pin_Code.PinCode_Pt = 0;
		    }
		}
		
	}
    if(Screen_Mode == MODE_Admin)
	{
		if(Key_status[0] == KEY_SHORT_PRESS)
		{
			Pin_Code.PinCodeNum[Pin_Code.PinCode_Pt ++] = 1;
			Key_status[0] = RESET_KEY_STATUS;
		}
		if(Key_status[1] == KEY_SHORT_PRESS)
		{
			Pin_Code.PinCodeNum[Pin_Code.PinCode_Pt ++] = 2;
			Key_status[1] = RESET_KEY_STATUS;
		}
		if(Key_status[2] == KEY_SHORT_PRESS)
		{
			Pin_Code.PinCodeNum[Pin_Code.PinCode_Pt ++] = 3;
			Key_status[2] = RESET_KEY_STATUS;
		}
		if(Key_status[3] == KEY_SHORT_PRESS)
		{
			Pin_Code.PinCodeNum[Pin_Code.PinCode_Pt ++] = 4;
			Key_status[3] = RESET_KEY_STATUS;
		}
	}
	if(Screen_Mode == MODE_ResetPincode)
	{
		if(Key_status[0] == KEY_SHORT_PRESS)
		{
			Pin_Code.PinCodeNum[Pin_Code.PinCode_Pt ++] = 1;
			Key_status[0] = RESET_KEY_STATUS;
		}
		if(Key_status[1] == KEY_SHORT_PRESS)
		{
			Pin_Code.PinCodeNum[Pin_Code.PinCode_Pt ++] = 2;
			Key_status[1] = RESET_KEY_STATUS;
		}
		if(Key_status[2] == KEY_SHORT_PRESS)
		{
			Pin_Code.PinCodeNum[Pin_Code.PinCode_Pt ++] = 3;
			Key_status[2] = RESET_KEY_STATUS;
		}
		if(Key_status[3] == KEY_SHORT_PRESS)
		{
			Pin_Code.PinCodeNum[Pin_Code.PinCode_Pt ++] = 4;
			Key_status[3] = RESET_KEY_STATUS;
		}
	}
}// end key_handler()

void set_digicode(void)
{
    u32 pin_code_preset_number;
    u8 pin_code_high = 0;
    u8 pin_code_sheft = 0;
	pin_code_high = Pin_Code.PinCodeNum[0] * 10 + Pin_Code.PinCodeNum[1];
	if((Pin_Code.PinCodeNum[1] == 1) || (Pin_Code.PinCodeNum[1] == 2))
	{
		pin_code_sheft = (Pin_Code.PinCodeNum[1] - 1) * 16 + (Pin_Code.PinCodeNum[2] - 1) * 4 + Pin_Code.PinCodeNum[3] - 1;
	}
	else if((Pin_Code.PinCodeNum[1] == 3) || (Pin_Code.PinCodeNum[1] == 4))
	{
		pin_code_sheft = (Pin_Code.PinCodeNum[1] - 3) * 16 + (Pin_Code.PinCodeNum[2] - 1) * 4 + Pin_Code.PinCodeNum[3] - 1;
	}
	pin_code_preset_number = 0x80000000 >> pin_code_sheft;
	switch(pin_code_high)
	{
		case 11:
		case 12:
		{
			DigicodeArray1Value |= pin_code_preset_number; 
			menu_ee_index = VAR_USER_DIGICODEARRAY1;
			menu_needs_ee = 1;
			break;
		}
		case 13:
		case 14:
		{
			DigicodeArray2Value |= pin_code_preset_number; 
			menu_ee_index = VAR_USER_DIGICODEARRAY2;
			menu_needs_ee = 1;
			break;
		}
		case 21:
		case 22:
		{
			DigicodeArray3Value |= pin_code_preset_number; 
			menu_ee_index = VAR_USER_DIGICODEARRAY3;
			menu_needs_ee = 1;
			break;
		}
		case 23:
		case 24:
		{
			DigicodeArray4Value |= pin_code_preset_number; 
			menu_ee_index = VAR_USER_DIGICODEARRAY4;
			menu_needs_ee = 1;
			break;
		}
		case 31:
		case 32:
		{
			DigicodeArray5Value |= pin_code_preset_number; 
			menu_ee_index = VAR_USER_DIGICODEARRAY5;
			menu_needs_ee = 1;
			break;
		}
		case 33:
		case 34:
		{
			DigicodeArray6Value |= pin_code_preset_number; 
			menu_ee_index = VAR_USER_DIGICODEARRAY6;
			menu_needs_ee = 1;
			break;
		}
		case 41:
		case 42:
		{
			DigicodeArray7Value |= pin_code_preset_number; 
			menu_ee_index = VAR_USER_DIGICODEARRAY7;
			menu_needs_ee = 1;
			break;
		}
		case 43:
		case 44:
		{
			DigicodeArray8Value |= pin_code_preset_number; 
			menu_ee_index = VAR_USER_DIGICODEARRAY8;
			menu_needs_ee = 1;
			break;
		}
		default:break;
	}        
}

/***********************************************************************************************************************
*                             Copyright 2016 Linde Material Handling. All rights reserved.                             *
***********************************************************************************************************************/

